package com.starry.module.system.core.user.mapper;

import com.starry.core.common.domain.vo.PageVo;
import com.starry.db.core.mapper.BaseMapperX;
import com.starry.db.core.query.LambdaQueryWrapperX;
import com.starry.module.system.api.user.domain.qo.SysUserPageQo;
import com.starry.module.system.api.user.domain.vo.SysUserDtlVo;
import com.starry.module.system.api.user.domain.vo.SysUserVo;
import com.starry.module.system.core.user.entity.SysUser;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Set;

/**
 * 系统用户-数据库服务层
 *
 * @author xiaoke
 */
@Mapper
public interface SysUserMapper extends BaseMapperX<SysUser> {

    /**
     * 分页查询
     *
     * @param pageQo 分页参数
     * @return PageVo<SysUser>
     */
    default PageVo<SysUser> selectPage(SysUserPageQo pageQo) {
        return selectPage(pageQo, new LambdaQueryWrapperX<SysUser>()
                .likeIfPresent(SysUser::getUsername, pageQo.getUsername())
                .likeIfPresent(SysUser::getPhone, pageQo.getPhone())
                .likeIfPresent(SysUser::getEmail, pageQo.getEmail())
                .eqIfPresent(SysUser::getDeptId, pageQo.getDeptId())
                .eqIfPresent(SysUser::getSex, pageQo.getSex())
                .eqIfPresent(SysUser::getPostId, pageQo.getPostId())
                .eqIfPresent(SysUser::getStatus, pageQo.getStatus())
        );
    }

    /**
     * 批量插入用户岗位
     *
     * @param userId     用户ID
     * @param postIdList 岗位ID列表
     */
    void insertBatchUserPost(@Param("userId") Long userId,
                             @Param("postIdList") Set<Long> postIdList,
                             @Param("createTime") LocalDateTime createTime,
                             @Param("createId") Long createId,
                             @Param("createName") String createName
    );

    /**
     * 获取用户信息（用户名、手机号、邮箱）
     *
     * @param value value
     * @return 用户信息
     */
    default SysUser selectByValue(String value) {
        return selectOne(new LambdaQueryWrapperX<SysUser>()
                .or(o -> o.eq(SysUser::getUsername, value))
                .or(o -> o.eq(SysUser::getPhone, value))
                .or(o -> o.eq(SysUser::getEmail, value))
        );
    }

    /**
     * 根据用户名查询用户列表
     *
     * @param pageQo 分页参数
     * @return 用户列表
     */
    default List<SysUser> selectUserList(SysUserPageQo pageQo) {
        return selectList(new LambdaQueryWrapperX<SysUser>()
                .likeIfPresent(SysUser::getUsername, pageQo.getUsername())
                .eqIfPresent(SysUser::getStatus, pageQo.getStatus())
        );
    }

    /**
     * 根据用户ID查询用户权限
     *
     * @param userId 用户ID
     * @return 用户权限
     */
    Set<String> getByIdUserPerms(Long userId);

    /**
     * 批量插入用户角色
     *
     * @param userId     用户ID
     * @param roleIdList 角色ID列表
     */
    void insertBatchUserRole(@Param("userId") Long userId,
                             @Param("roleIdList") Set<Long> roleIdList,
                             @Param("createTime") LocalDateTime createTime,
                             @Param("createId") Long createId,
                             @Param("createName") String createName
    );

    /**
     * 根据用户ID查询岗位ID列表
     *
     * @param userId 用户ID
     * @return 岗位ID列表
     */
    Set<Long> selectByUserIdPostIdList(@Param("userId") Long userId);

    /**
     * 根据用户ID查询角色ID列表
     *
     * @param userId 用户ID
     * @return 角色ID列表
     */
    Set<Long> selectByUserIdRoleIdList(@Param("userId") Long userId);

    /**
     * 根据用户ID查询机构ID列表
     *
     * @param userId 用户ID
     * @return 机构ID列表
     */
    Set<Long> selectByUserIdDeptIdList(@Param("userId") Long userId);

    /**
     * 批量删除用户岗位
     *
     * @param userId     用户ID
     * @param postIdList 角色ID列表
     */
    void deleteBatchUserPost(@Param("userId") Long userId,
                             @Param("postIdList") Set<Long> postIdList
    );

    /**
     * 批量删除用户角色
     *
     * @param userId     用户ID
     * @param roleIdList 角色ID列表
     */
    void deleteBatchUserRole(
            @Param("userId") Long userId,
            @Param("roleIdList") Set<Long> roleIdList
    );

    /**
     * 批量插入用户机构
     *
     * @param userId     用户ID
     * @param deptIdList 机构ID列表
     * @param createTime 当前时间
     * @param createId   创建者ID
     * @param createName 创建者用户名
     */
    void insertBatchUserDept(
            @Param("userId") Long userId,
            @Param("deptIdList") Set<Long> deptIdList,
            @Param("createTime") LocalDateTime createTime,
            @Param("createId") Long createId,
            @Param("createName") String createName
    );

    /**
     * 批量删除用户机构
     *
     * @param userId     用户ID
     * @param deptIdList 机构ID列表
     */
    void deleteBatchUserDept(
            @Param("userId") Long userId,
            @Param("deptIdList") Set<Long> deptIdList
    );

    /**
     * 根据用户ID查询用户详情
     *
     * @param id 用户ID
     * @return 用户详情
     */
    SysUserDtlVo selectDtlById(Long id);

    /**
     * 分页查询总数
     *
     * @param pageQo 分页参数
     * @return 总数
     */
    Long selectPageTotal(SysUserPageQo pageQo);

    /**
     * 分页查询用户
     *
     * @param pageQo 分页参数
     * @return 用户列表
     */
    List<SysUserVo> selectPageUser(SysUserPageQo pageQo);


    /**
     * 校验是否是租户管理员
     *
     * @param userIdList 用户ID列表
     * @return 是否是租户管理员
     */
    default boolean validateIsTenantUser(Set<Long> userIdList) {
        return selectCount(new LambdaQueryWrapperX<SysUser>()
                .in(SysUser::getId, userIdList)
                .and(o -> o.eq(SysUser::getTenantAdmin, true))
        ) == 1;
    }

}

